<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>贪吃蛇</title>
	<style type="text/css">
		@font-face{
			font-family: Screen;
			src: url('screen.ttf')
		}
		*{
			margin: 0;
			overflow: hidden;
		}
		body{
			background-color: gray;
			font-family: 'Microsoft Yahei';
		}
		.head{
			height: 60px;
			width: 702px;
			margin: 0 auto;
		}
		.head .time,.head .point{
			height: 50px;
			width: 70px;
			font-family: 'Screen';	
			font-size: 30px;
			background-color: #fff;
			margin: 10px;
			line-height: 35px;
			text-align: center;
			border-width: 3px 3px 0 3px;
			border-style: solid;
			border-color: blue;
			border-top-right-radius: 5px; 
			border-top-left-radius: 5px; 
		}
		.head .time{
			float: left;
			color: red;
		}
		.head .title{
			background-image: url("snake.png");
			background-size: 360px;
			background-position: 80px;
			background-repeat: no-repeat;
			width: 500px;
			height: 60px;
			float: left;
		}
		.head .point{
			float: right;
		}
		.head p{
			font-size: 14px;
			line-height: 14px;
		}
		canvas{
			display: block;
			margin: 0 auto;
			background-color: #fff;
			border-radius: 15px;
			border: 5px solid blue;
		}
		.bottom{
			/*float: left;*/
			height: 60px;
			line-height: 60px;
			width: 702px;
			margin: 0 auto;
		}
		.bottom .keys{
			display: inline-block;
			vertical-align:middle;
			width: 85px;
		}
		.bottom .keys p{
			display: inline-block;
			width: 20px;
			height: 20px;
			font-size: 12px;
			color: #1a89c7;
			background-color: #fff;
			border: 3px solid #1a89c7;
			border-radius: 5px;
			text-align: center;
			/*vertical-align:top;*/
			line-height: 20px;
			float: left;
			margin: 0 0 2px 2px;
		}
		.bottom .keys .hide{
			visibility: hidden;
		}
		.bottom .radios{
			display: inline-block;			
			vertical-align:middle;
		}
		.bottom button{
			height: 35px;
			color: #1a89c7;
			background-color: #fff;
			border: 3px solid #1a89c7;
			border-radius: 5px;
			margin-left: 10px;
			cursor: pointer;
		}
		.flex{
			display: none;
		}
		.flex .flexwindow{
			position: fixed;
			left: 50%;
			top: 60px;
			height: 482px;
			width: 300px;
			margin-left: -150px;
			background-color: #fff;
			text-align: center;
			border: 5px solid red;
			padding: 10px;
		}
		.flex .flexwindow #finalpoint{
			font-family: 'Screen';
			font-size: 48px;
			line-height: 64px;
		}
		.flex .flexwindow #close{
			height: 35px;
			color: #1a89c7;
			background-color: #fff;
			border: 3px solid #1a89c7;
			border-radius: 5px;
			margin-left: 10px;
			cursor: pointer;
		}
		.flex .mask{
			background-color: #333;
			opacity: 0.5;
			position: fixed;
			top: 0;
			left: 0;
		}
	</style>
</head>
<body>
	<div class="head">
		<div class="time" id="time"><p>TIME</p><span id="second">60</span></div>
		<div class="title"></div>
		<div class="point"><p>POINT</p><span id="point">0</span></div>
	</div>
	<canvas id="canvas" width="702" height="502"></canvas>
	<div class="bottom">
		<span>操作方式：</span>
		<div class="keys">
			<p class="hide"> </p>
			<p>W</p>
			<p class="hide"> </p>
			<p>A</p>
			<p>S</p>
			<p>D</p>
		</div>
		<span>OR</span>
		<div class="keys">
			<p class="hide"> </p>
			<p>↑</p>
			<p class="hide"> </p>
			<p>←</p>
			<p>↓</p>
			<p>→</p>
		</div>
		<span>模式选择：</span>
		<div class="radios" id="radios">
			<input type="radio" name="BoundaryModel" value="0" id="noboundary" onclick="boundaryChange()" checked="checked"><label for="noboundary">无界</label>
			<input type="radio" name="BoundaryModel" value="1" id="boundary"   onclick="boundaryChange()"><label for="boundary">有界</label>
			<input type="radio" name="LimitModel"    value="0" id="limitless"  onclick="limitChange()"> <label for="limitless">不计时</label>
			<input type="radio" name="LimitModel"    value="1" id="limit"      onclick="limitChange()" checked="checked"><label for="limit">计时</label>
		</div>
		<button id="button">开始游戏</button>
	</div>
	<div class="flex" id="flex">
		<div class="mask" id="mask"></div>
		<div class="flexwindow">
			<p>你的成绩：</p>
			<p id="finalpoint"></p>
			<button id="close">关闭</button>
		</div>		
	</div>
</body>
	<script type="text/javascript">
		var mask = document.getElementById("mask");
		mask.style.height = window.innerHeight+"px";
		mask.style.width = window.innerWidth+"px";
		var canvas = document.getElementById("canvas");
		var ctx = canvas.getContext("2d");

		function initBlackGround(){
			ctx.fillStyle = "#ddd";
			for(var i=0;i<25;i++)
				for(var j=0;j<35;j++)
					ctx.fillRect(20*j+2,20*i+2,18,18);
		}

		function fillBlock(i,j,color){
			ctx.fillStyle = color;
			ctx.fillRect(20*j+2,20*i+2,18,18);
		}

		var boundaryModel;
		var limitModel;
		function initModels(){
			var boundy = document.getElementsByName("BoundaryModel");
			for(var i=0;i<2;i++)if(boundy[i].checked)boundaryModel=boundy[i].value;
			var limit = document.getElementsByName("LimitModel");
			for(i=0;i<2;i++)if(limit[i].checked)limitModel=limit[i].value;
		}

		function freshModels(){
			var boundy = document.getElementsByName("BoundaryModel");
			for(var i=0;i<2;i++)if(boundy[i].checked)boundaryModel=boundy[i].value;
			var limit = document.getElementsByName("LimitModel");
			for(i=0;i<2;i++)if(limit[i].checked)limitModel=limit[i].value;
		}

		function boundaryChange(){
			var boundy = document.getElementsByName("BoundaryModel");
			for(var i=0;i<2;i++)
				if(boundy[i].checked)
					if(i==1){
						canvas.style.borderColor= "red";
					}else{
						canvas.style.borderColor= "blue";
					}				
		}

		function limitChange(){
			var limit = document.getElementsByName("LimitModel");
			var time = document.getElementById("time");
			for(var i=0;i<2;i++)
				if(limit[i].checked)
					if(i==1){
						time.style.visibility= "visible";
					}else{
						time.style.visibility= "hidden";
					}				
		}

		function SnakeHead(){
			this.i = -1;
			this.j = -1;
		}

		function SnakeTail(){
			this.i = -1;
			this.j = -1;
		}

		function Snake(){
			this.head = new SnakeHead();
			this.tail = [];
		}

		var snake;
		function initSnake(){
			snake = new Snake();
			snake.head.i = 1;
			snake.head.j = 4;
			var firsttail = new SnakeTail();
			firsttail.i = 1;
			firsttail.j = 3;
			snake.tail.push(firsttail);
			drawSnake(snake);
		}

		function Feed(){
			this.i = -1;
			this.j = -1;
		}

		var feed;
		function initFeed(){
			feed = new Feed();
			do{feed.i = parseInt(Math.random()*25,10);}while(feed.i==1);
			feed.j = parseInt(Math.random()*35,10);
			drawFeed();
		}

		function newFeed(){
			feed.i = parseInt(Math.random()*25,10);
			feed.j = parseInt(Math.random()*35,10);
			for(var k=0;k<snake.tail.length;k++){
				if(snake.tail[k].i==feed.i&&snake.tail[k].j==feed.j){
					feed.i = parseInt(Math.random()*25,10);
					feed.j = parseInt(Math.random()*35,10);
				}
			}
		}

		function drawFeed(){
			fillBlock(feed.i,feed.j,"blue");
		}

		function drawTail(t){
			fillBlock(t.i,t.j,"green");
		}

		function drawSnake(s){
			s.tail.forEach(drawTail);
			fillBlock(s.head.i,s.head.j,"red");			
		}

		function isEatFeed(){
			if(snake.head.i==feed.i && snake.head.j==feed.j)
				return true;
			else 
				return false;
		}

		function isBoom(){
			for(var k=0;k<snake.tail.length;k++){
				if(snake.head.i==snake.tail[k].i&&snake.head.j==snake.tail[k].j){
					gameOver();
					return true;
				}
			}
			return false;
		}

		function isOut(){
			if(snake.head.i<0 || snake.head.j<0 || snake.head.i>24 || snake.head.j>34){
				gameOver();
				return true;
			}			
			return false;
		}

		function isTimeout(){
			if(second==0){
				gameOver();
				return true;
			}			
			return false;
		}

		var point=0;
		function initPoint(){
			point=0;
			document.getElementById("point").innerHTML = point;
		}

		function score(){
			point++;
			document.getElementById("point").innerHTML = point;
		}

		var second=60;
		function initTime(){
			second=60;
			document.getElementById("second").innerHTML = second;
		}

		function gameOver(){
			btn.innerHTML = "重新开始";
			btn.removeEventListener('click',parse);
			btn.addEventListener('click',again);
			document.getElementById("noboundary").disabled=false;
			document.getElementById("boundary").disabled=false;
			document.getElementById("limitless").disabled=false;
			document.getElementById("limit").disabled=false;
			document.getElementById("radios").removeEventListener('click',changeDisabled);
		}

		document.onkeydown=function(event){
			var e = event || window.event;
			if(e&&keydownwindow==1){
				switch(e.keyCode){
					case 37:case 65://左
						if(moveforword!=2)moveforword=0;
						keydownwindow=0;
						break;

					case 38:case 87://上
						if(moveforword!=3)moveforword=1;
						keydownwindow=0;
						break;

					case 39:case 68://右
						if(moveforword!=0)moveforword=2;
						keydownwindow=0;
						break;

					case 40:case 83://下
						if(moveforword!=1)moveforword=3;
						keydownwindow=0;
						break;
				}
			}
		}

		var keydownwindow=1;
		var account=0;
		function move(){
			initBlackGround();	
			var lasttail = new SnakeTail();
			lasttail.i = snake.tail[snake.tail.length-1].i;		
			lasttail.j = snake.tail[snake.tail.length-1].j;		
			for(var k = snake.tail.length-1;k>0;k--){
				snake.tail[k].i = snake.tail[k-1].i;
				snake.tail[k].j = snake.tail[k-1].j;
			}
			snake.tail[0].i = snake.head.i;
			snake.tail[0].j = snake.head.j;
			switch(moveforword){
				case 0:
					snake.head.j -= 1;
					if(boundaryModel==0)if(snake.head.j<0)snake.head.j=34;
					break;

				case 1:
					snake.head.i -= 1;
					if(boundaryModel==0)if(snake.head.i<0)snake.head.i=24;
					break;

				case 2:
					snake.head.j += 1;
					if(boundaryModel==0)if(snake.head.j>34)snake.head.j=0;
					break;

				case 3:
					snake.head.i += 1;
					if(boundaryModel==0)if(snake.head.i>24)snake.head.i=0;
					break;
			}
			keydownwindow=1;
			if(limitModel==1){
				account++;
				if(account==10){
					second--;
					document.getElementById("second").innerHTML = second;
					account=0;
				}
				if(isTimeout()){
					clearInterval(animate);
					animate = setInterval(boom,300);
				}
			}
			if(isEatFeed()){
				snake.tail.push(lasttail);
				score();
				newFeed();
			}
			if(isBoom()){
				clearInterval(animate);
				animate = setInterval(boom,300);
			}
			if(boundaryModel==1)
				if(isOut()){
					clearInterval(animate);
					animate = setInterval(boom,300);
				}			
			drawSnake(snake);
			drawFeed();
		}

		var flag = 1;
		var flexcount = 0;
		var flex = document.getElementById("flex");
		function boom(){
			if(flag==0){
				if(boundaryModel==1)canvas.style.borderColor= "red";
				initBlackGround();
				drawSnake(snake);
				drawFeed();
				flag=1;
				flexcount++;
			}
			else{
				if(boundaryModel==1)canvas.style.borderColor= "#fff";
				initBlackGround();
				flag=0;
			}
			if(flexcount==3){
				clearInterval(animate);
				flex.style.display="block";
				document.getElementById("finalpoint").innerHTML = point;
			}
		}

		var moveforword;
		function init(){
			initBlackGround();
			initModels();
			initTime();
			initPoint();
			initSnake();
			initFeed();
			moveforword=2;
		}

		init();

		var animate;
		var btn = document.getElementById("button");
		btn.addEventListener('click',begin);
		function begin(){
			animate = setInterval(move,100);
			btn.innerHTML = "暂停游戏";
			btn.removeEventListener('click',begin);
			btn.addEventListener('click',parse);
			freshModels();
			document.getElementById("noboundary").disabled=true;
			document.getElementById("boundary").disabled=true;
			document.getElementById("limitless").disabled=true;
			document.getElementById("limit").disabled=true;
			document.getElementById("radios").addEventListener('click',changeDisabled);
		}
		function parse(){
			clearInterval(animate);
			btn.innerHTML = "继续游戏";
			btn.removeEventListener('click',parse);
			btn.addEventListener('click',continu);
		}
		function continu(){
			animate = setInterval(move,100);
			btn.innerHTML = "暂停游戏";
			btn.removeEventListener('click',continu);
			btn.addEventListener('click',parse);
		}
		function again(){
			init();
			animate = setInterval(move,100);
			btn.innerHTML = "暂停游戏";
			btn.removeEventListener('click',again);
			btn.addEventListener('click',parse);
			freshModels();
			document.getElementById("noboundary").disabled=true;
			document.getElementById("boundary").disabled=true;
			document.getElementById("limitless").disabled=true;
			document.getElementById("limit").disabled=true;
			document.getElementById("radios").addEventListener('click',changeDisabled);
			if(boundaryModel==0)canvas.style.borderColor= "blue";
			else canvas.style.borderColor= "red";
		}
		function changeDisabled(){
			alert("游戏开始后不能更换模式！");
			parse();
		}
		document.getElementById("close").addEventListener('click',function(){
			flex.style.display= "none" ;
			flexcount = 0;
		});
	</script>
</html>